import * as fs from 'fs/promises';
import * as http from 'http';
import { AnyARecord } from 'node:dns';
import { Message, request, server, w3cwebsocket, connection } from 'websocket';
import { Operation, OperationType } from './defines';
import GameServerPlayer from './serverPlayer';

export default class Room {

    static curRoomIdx: number = 0;

    roomId?: number;
    playerList: GameServerPlayer[] = [];
    /**scoket */
    websocketServer?: server;
    /**总的帧缓存用于重连 */
    totalFrameArrayCache: Operation[] = [];
    /**缓存客户端发送来的帧数据，在结算后置空 */
    curFrameArrayCache: Operation[] = [];
    httpServer: http.Server;
    get connections(): connection[] {
        let cons: connection[] = [];
        if (this.websocketServer && this.websocketServer.connections) {
            cons = this.websocketServer.connections;
        }
        return cons;
    }
    constructor(httpServer: http.Server) {
        this.httpServer = httpServer;
        this.init();
    }
    init() {
        const websocketServer = new server({
            httpServer: this.httpServer,
            autoAcceptConnections: false
        });
        websocketServer.on('request', this.onRequest.bind(this));
        this.websocketServer = websocketServer;
    }
    serverClose() {
        if (this.websocketServer) {
            this.websocketServer.connections.forEach(v => {
                v.close();
            })
        }
    }
    distributeRoomNum() {
        return Room.curRoomIdx++;
    }
    /**过滤请求 */
    originIsAllowed(origin: string) {
        if (this.connections.length < 3) {
            return true;
        }
        return false;
    }
    /**当有请求连接 */
    onRequest(req: request) {
        let curConnection: connection;
        console.log('request', req)
        if (!this.originIsAllowed(req.origin)) {
            // Make sure we only accept requests from an allowed origin
            req.reject();
            console.log((new Date()) + '拒绝连接' + req.origin);
            return;
        }
        curConnection = req.accept('', req.origin);
        /**当接收到数据 */
        curConnection.on('message', (message: any) => {
            let type = message.type;
            let data = message.utf8Data || message.binaryData;
            if (type === 'utf8') {
                data = JSON.parse(data);
                console.log('接收到字符串数据：' + JSON.stringify(data));
                let replyData = '';
                if (data.type == OperationType.getToken) {
                    let timeStamp = new Date().getTime();
                    let randNum = Math.floor(Math.random() * 100000);
                    replyData = 'token_' + timeStamp + '_' + randNum + '_' + req.key;
                } else if (data.type == OperationType.getRoomNum) {
                    curConnection.sendUTF(this.distributeRoomNum());
                } else if (data.type == OperationType.updateFrame) {
                    curConnection.sendUTF('当前节点状态');
                }
                curConnection.sendUTF(data)
            }
            else if (type === 'binary') {
                console.log('接收到二进制数据：' + data.length);
                curConnection.sendBytes(data);
            }
        });
        /**当连接断开 */
        curConnection.on('close', (reasonCode: any, description: any) => {
            console.log((new Date()) + '客户端断开连接：' + curConnection.remoteAddress, reasonCode, description);
            this.showCurConnectionCount();
        });
        this.showCurConnectionCount();
    }
    showCurConnectionCount() {
        console.log((new Date()) + '连接客户端成功,目前已连接', this.connections.length, '个');
    }

    sendStrToAllClient() {
        let datas = this.curFrameArrayCache;
        let connections = this.websocketServer && this.websocketServer.connections;
        // console.log('sendStrToAllClient1', datas && datas.length, connections && connections.length);
        if (connections && connections.length && datas && datas.length) {
            for (let data of datas) {
                for (let i = 0; i < connections.length; i++) {
                    // console.log('sendStrToAllClient2');
                    let connect = connections[i];
                    connect.sendUTF(data);
                }
            }
        }
        this.curFrameArrayCache = [];
    }
}
